package com.gao.b_channel.a;

import org.junit.Test;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * @author gao
 * @time 2020/06/18 19:14:43
 */
public class App {
    // 通过本地IO的方式来获取通道：完成文件复制。
    @Test
    public void test() throws IOException {
        ByteBuffer buf = ByteBuffer.allocate(3);
        FileInputStream in = new FileInputStream("file\\1.txt");
        FileOutputStream out = new FileOutputStream("file\\2.txt");

        FileChannel srcChannel = in.getChannel();
        FileChannel destChannel = out.getChannel();

        while (srcChannel.read(buf) > 0) {
            buf.flip();
            destChannel.write(buf);
            buf.clear();
        }

        srcChannel.close();
        destChannel.close();
    }

    // 通过jdk1.7中的FileChannel.open()方法获取通道：复制文件
    @Test
    public void test2() throws IOException {
        ByteBuffer buf = ByteBuffer.allocate(5);

        FileChannel srcChannel = FileChannel.open(Paths.get("file\\1.txt"), StandardOpenOption.READ);
        Set<StandardOpenOption> options = new HashSet<>();
        // 以下选项表示：写模式
        options.add(StandardOpenOption.WRITE);
        // 以下选项表示：文件不存在时就创建，如果已经存在就不创建
        options.add(StandardOpenOption.CREATE);
        FileChannel destChannel = FileChannel.open(Paths.get("file\\2.txt"), options);

        while (srcChannel.read(buf) > 0) {
            buf.flip();
            destChannel.write(buf);
            buf.clear();
        }

        srcChannel.close();
        destChannel.close();
    }

    // FileChannel可以通过它的transfer()方法来实现数据的传输：
    @Test
    public void test3() throws IOException {
        FileInputStream in = new FileInputStream("file\\1.txt");
        FileOutputStream out = new FileOutputStream("file\\2.txt");

        FileChannel srcChannel = in.getChannel();
        FileChannel destChannel = out.getChannel();

        // FileChannel srcChannel = FileChannel.open(Paths.get("file\\1.txt"), StandardOpenOption.READ);
        // FileChannel destChannel = FileChannel.open(Paths.get("file\\2.txt"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);

        srcChannel.transferTo(0, srcChannel.size(), destChannel);
        // 或者
        // destChannel.transferFrom(srcChannel,0, srcChannel.size());

        srcChannel.close();
        destChannel.close();

    }

    /*
        以下例子证明了Channel是双向的，及支持读，也支持写
     */
    @Test
    public void test4() throws IOException {
        FileChannel channel = FileChannel.open(Paths.get("file\\3.txt"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);

        ByteBuffer buf = ByteBuffer.allocate(100);

        // 读
        int readBytes = channel.read(buf);

        if (readBytes > 0) {
            byte[] byteArray = new byte[readBytes];
            buf.flip();
            buf.get(byteArray);
            String body = new String(byteArray);
            System.out.println(body);
        }

        // 写
        buf.clear();
        buf.put("where is she".getBytes());
        buf.flip();
        channel.write(buf);
        buf.clear();


    }

}
